安卓开发——操作栏(Action Bar)的学习

操作栏具有显示应用图标,标题,安置菜单选项,配置应用图标为导航按钮等功能。

选项菜单(Option Menus)

在新版本的安卓中创建选项菜单并不难,步骤也很简单:

在XML中定义选项菜单

  首先创建一个定义菜单的xml文件,这个文件放在res/menu目录下(没有的话自行创建)。在该xml文件下根标签为<menu>,然后使用<item>标签可以定义具体的菜单项。每个菜单项可以带有图标和文本显示。示例如下:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_item1"
android:icon="@android:drawable/ic_menu_add"
android:title="@string/item1_title"
android:showAsAction="ifRoom|withText">
</item>
</menu>
  1. android:icon —— 定义了菜单项的图标
  2. android:title —— 定义了菜单项的标题
  3. android:showAsAction —— showAsAction属性用于指定菜单选项是显示在操作栏上,还是隐藏到溢出菜单(overflow menu)中。该属性当前设置为ifRoom和withText的一个组合值。因此,只要空间足够,菜单项图标及其文字描述都会显示在操作栏上。

实例化菜单

  无论是在Activity还是在Fragment中初始化菜单都是只需要重载onCreateOptionsMenu()方法后,使用参数中的MenuInflater来初始化菜单即可。

1
2
3
4
5
6
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
/* 初始化菜单选项 */
inflater.inflate(R.menu.menu_fragment_crime_list, menu);
}

PS:Fragment的onCreateOptionsMenu()方法是由FragmentManager调用的,同时我们需要在Fragment重载的onCreate()方法中申明需要接受选项菜单回掉函数。

1
2
3
4
5
6
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Fragment的onCreate()中的设置,Activity中不需要 */
setHasOptionsMenu(true);
}

响应菜单项选择

  只需要重载onOptionsItemSelected()方法即可,在方法中负责处理各个菜单项的点击操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.menu_itme1:
//...
return true;
case R.id.menu_itme2:
//...
return true;
default:
return super.onOptionsItemSelected(item);
}
}

实现层级导航

  层级导航则是平时我们在应用中看到的左上方的< 返回这样的按钮,这里实现的是点击应用图标可以实现返回上一个Activity视图中。

启用应用图标导航

  只要调用DisplayHomeAsUpEnabled(true)方法即可启用。该方法Activity和Fragment中都有,并且该方法是在API11以后才加入的,如果开发的应用版本低于这个,则需要做相应检测。

(1)Activity中设置:

1
2
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getActionBar().setDisplayHomeAsUpEnabled(true);

(2)Fragment中设置:

1
2
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);

响应返回按钮

  和菜单项按钮的操作一样,我们只需要重载onOptionsItemSelected()方法,并在里面处理按钮事件即可。
  同菜单选项一样别忘了在Fragment中还需要额外的设置,即在Fragment的onCreate()中设置setHasOptionsMenu(true);
  想要实现返回操作,主要有两种实现方式,方式一如代码中所示。但是方法二的实现会更好,只要通过在AndroidMenifest.xml中给Activity配置元数据<meta-data>,即可配置该Activity的父Activity。这样子的方式比方法一要灵活,如果我们需要改变返回的父Activity,则只需要修改xml配置文件就可以了。

(1)AndroidMenifest.xml配置。

1
2
3
4
<activity android:name=".ChildActivity" android:label="@string/app_name">
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value=".ParentActivity"></meta-data>
</activity>

(2)重载onOptionsItemSelected()方法处理按钮事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
/* 方法一实现返回上一级页面
Intent i = new Intent(getActivity(), CrimeListActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
*/
/*
第二种方法,配合meta-data使用,查看是否定义了父ACTIVITY,然后结合NavUtils类实现返回上一级
NavUtils类的实现代码既简洁又优雅。其次, 使用NavUtils类也可实现在manifest配置文件中统一管理activity间的关系。如果activity
间的关系发生改变,无需费力地去修改Java代码,我们只要简单修改配置文件中的一行代码即可。
*/
if(NavUtils.getParentActivityName(getActivity()) != null)
NavUtils.navigateUpFromSameTask(getActivity());
return true;
default: return super.onOptionsItemSelected(item);
}
}

控制导航按钮的显示

  如果采用上面的方法二来实现导航按钮,我们还可以结合NavUtils类来实现对导航按钮的控制。
  我们可以先判断当前Activity或Fragment是否含有父Activity,再决定是否启用图标导航功能。

1
2
if(NavUtils.getParentActivityName(getActivity()) != null)
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);

参考资料

  1. 《Android编程权威指南 第四版》